#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#include "cQuate.h"

float solve(char *pData, int len)
{
	len = remBraces(pData, len);
    int a = smartSplit(pData, len);
	if(a == 0)
	{
		switch (*pData)
		{
			case 's' : return sin(solve(pData+4, len-5)); break;
			case 'c' : return cos(solve(pData+4, len-5)); break;
			case 't' : return tan(solve(pData+4, len-5)); break;
		}
		return atof(pData);
		
	}else{
		switch(pData[a])
		{
			case '+': return solve(pData, a) + solve(pData+a+1, len-a-1); break;
			case '-': return solve(pData, a) - solve(pData+a+1, len-a-1); break;
			case '*': return solve(pData, a) * solve(pData+a+1, len-a-1); break;
			case '/': return solve(pData, a) / solve(pData+a+1, len-a-1); break;
			case '^': return pow(solve(pData, a), solve(pData+a+1, len-a-1)); break;
		}
	}
	return atof(pData);
}

int remBraces(char *&p, int len)
{
	int count = 1;
	if(*p != '(')
		return len;
	for(int a = 1;a < len-1;a++)
	{
		if(p[a] == '(')
			count++;
		if(p[a] == ')')
			count--;
		if(count == 0)
			return len;
	}
	p+=1;
	return len-2;
}

int smartSplit(char *pData, int len)
{
    int count = 0;
    int pos =0;
    int priorety = 4;
    for(int a = len-1;a > 0;a--)
    {
		if(pData[a] == '(')
			count++;
		if(pData[a] == ')')
			count--;
		if(count == 0 && a > 0)
		{
		    switch(pData[a])
		    {
		        case '+' :
		        {
		            if(pData[a-1] == '*' || pData[a-1] == '/' || pData[a-1] == '+' || pData[a-1] == '-')
					{
						return a-1;
					}else if(pData[a-1] == '^')
					{
					    if(priorety > 3)
                        {
                            pos = a-1;
                            a--;
                            priorety = 3;
                        }
					}else
					{
						return a;
					}
					 break;
		        }
		        case '-' :
		        {
		           if(pData[a-1] == '*' || pData[a-1] == '/' || pData[a-1] == '+' || pData[a-1] == '-')
				   {
						return a-1;
					}else if(pData[a-1] == '^')
					{
					    if(priorety > 3)
                        {
                            pos = a-1;
                            priorety = 3;
                        }
					}else
					{
						return a;
					}
					 break;
		        }
		        case '*' :
		        {
		            if(priorety > 2)
		            {
		                pos = a;
		                priorety = 2;
		            }
		            break;
		        }
		        case '/' :
		        {
		            if(priorety > 2)
		            {
		                pos = a;
		                priorety = 2;
		            }
		            break;
		        }
                case '^' :
		        {
		            if(priorety > 3 && a > pos)
		            {
		                pos = a;
		                priorety = 3;
		            }
		            break;
		        }
		    }
		}
	}
	if(pos > 0)
        return pos;
	return 0;
}